/**
 * Software License, Version 1.0
 * 
 * Copyright 2008 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgment:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgment may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or Granules, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called Granules, 
 * nor may Indiana University or Community Grids Lab or Granules appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 * WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 * NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 * INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 * INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 * "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 * LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 * ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 * GENERATED USING SOFTWARE.
 */
package cgl.granules.util;

import java.io.IOException;

/**
 * A matrix encapsulator where the Matrix is stored in column-major format for
 * faster reads from the underlying file system.
 * 
 * @author Shrideep Pallickara
 * 
 */
public class MatrixColumnMajor extends Matrix {

    public MatrixColumnMajor(String filename, int numberOfRows,
            int numberOfColumns, boolean rowFormat, int entriesType)
        throws IOException {

        super(filename, numberOfColumns, numberOfRows, rowFormat, entriesType);
    }


    public MatrixColumnMajor(String filename) throws IOException {
        super(filename);
    }


    @Override
    public synchronized int[][] readIntMatrix() throws IOException {
        return super.readIntMatrix();
    }


    @Override
    public synchronized int[] readIntMatrixColumn(int columnId)
        throws IOException {
        return super.readIntMatrixRow(columnId);
    }


    @Override
    public synchronized int readIntMatrixElement(int rowId, int columnId)
        throws IOException {
        return super.readIntMatrixElement(columnId, rowId);
    }


    @Override
    public synchronized int[] readIntMatrixRow(int rowId) throws IOException {
        return super.readIntMatrixColumn(rowId);
    }


    @Override
    public synchronized long[][] readLongMatrix() throws IOException {
        return super.readLongMatrix();
    }


    @Override
    public synchronized long[] readLongMatrixColumn(int columnId)
        throws IOException {
        return super.readLongMatrixRow(columnId);
    }


    @Override
    public synchronized long readLongMatrixElement(int rowId, int columnId)
        throws IOException {
        return super.readLongMatrixElement(columnId, rowId);
    }


    @Override
    public synchronized long[] readLongMatrixRow(int rowId) throws IOException {
        return super.readLongMatrixColumn(rowId);
    }


    @Override
    public synchronized void writeIntMatrixColumn(int columnId,
                                                  int[] columnValues)
        throws IOException {
        super.writeIntMatrixRow(columnId, columnValues);
    }


    @Override
    public synchronized void writeIntMatrixElement(int rowId, int columnId,
                                                   int value)
        throws IOException {
        super.writeIntMatrixElement(columnId, rowId, value);
    }


    @Override
    public synchronized void writeIntMatrixRow(int rowId, int[] rowValues)
        throws IOException {
        super.writeIntMatrixColumn(rowId, rowValues);
    }


    @Override
    public synchronized void writeLongMatrixColumn(int columnId,
                                                   long[] columnValues)
        throws IOException {
        super.writeLongMatrixRow(columnId, columnValues);
    }


    @Override
    public synchronized void writeLongMatrixElement(int rowId, int columnId,
                                                    long value)
        throws IOException {
        super.writeLongMatrixElement(columnId, rowId, value);
    }


    @Override
    public synchronized void writeLongMatrixRow(int rowId, long[] rowValues)
        throws IOException {
        super.writeLongMatrixColumn(rowId, rowValues);
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        int numOfRows = 16000;
        int numOfColumns = 16000;
        int entriesType = INT_ENTRIES;
        boolean rowMajorFormat = false;
        String filename = "MatrixB.txt";

        try {
            MatrixFactory matrixFactory = MatrixFactory.getInstance();

            Matrix matrixB =
                matrixFactory.getMatrix(filename, numOfRows, numOfColumns,
                                        entriesType, rowMajorFormat);

            long start = System.nanoTime();
            for (int i = 0; i < numOfRows; i++) {
                int[] columnAi = matrixB.createDenseIntColumn(numOfRows);
                matrixB.writeIntMatrixColumn(i, columnAi);
            }
            System.out.println("Time to write matrix[" + numOfRows + ","
                + numOfColumns + "] = "
                + ((System.nanoTime() - start) / 1000000) + " ms");

            start = System.nanoTime();
            for (int i = 0; i < 2000; i++) {
                System.out.print(i + " ");
                int[] columnAi = matrixB.readIntMatrixColumn(i);
            }
            System.out.println("Time to read matrix[" + numOfRows + ","
                + numOfColumns + "] = "
                + ((System.nanoTime() - start) / 1000000) + " ms");
            System.out.println("Test complete ...");
        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

    }
}
